//引入存储配置信息的js文件
let config = require('config');

//公共函数和websocket模块和页面实例
let util, ws, that;

//调用程序入口函数
App({

  //存放小程序运行时的公共数据
  globalData: {
    storeId: null,
    serviceAuth: '',
    _3rdSession: wx.getStorageSync('_3rdSession'),
    printerDeviceId: wx.getStorageSync('printerDeviceId'),
    loginData: {},
    userListData: {},
    foodMenuData: [],
    clearUnreadMsgUser: ''
  },

  //存放小程序某些实时状态
  status: {

    logout: false,
    
    logined: false,

    connected: false,

    recryConnecting: false,

    recryConnectDone: true,

    pageInit: false,

    authFailed: false
  
  },

  //获取到配置数据
  config: config.data,

  msgTarget: {
    
    sysMsg: [],

    userMsg: [],

    errMsg: []

  },

  /**
   * 初始化一些模块
   */

  init: function() {

    that = this;

    util = require('./utils/util');

    ws = require('./utils/websocket');

  },

  /**
   * 触发事件函数
   */

  target: function(target, event, msg) {

    let targets = that.msgTarget[target];

    for(var targetIndex in targets) {

      targets[targetIndex](event, msg);

    }

  },

  /**
   * 系统消息处理
   */

  systemMsgHandler: function(event, msg) {

    if(event == 'wsPair') {

      wx.hideNavigationBarLoading();

      if(msg.serviceName && msg.serviceAuth) {

        //存放服务员昵称
        util.globalData('serviceName', msg.serviceName);

        //存放服务员权限
        util.globalData('serviceAuth', msg.serviceAuth);

        //存放服务员管控桌号
        util.globalData('serviceTableNums', msg.serviceTableNums);

      }
        
      //将公共状态登录设置为已连接
      util.status('connected', true);

      return;

    }

    that.target('sysMsg', event, msg);

  },


  /**
   * 处理用户消息函数
   */

  userMsgHandler: function(event, msg) {
    console.log(msg);
    
    that.target('userMsg', event, msg);
    
  },

  /**
   * websocket消息处理函数
   */

  wsMsgHandler: function(data) {
    console.log(data.data);
    //判断错误码是否为0，不为0则发生了错误
    if(data.errCode && data.errCode == '0') {
      //判断是否存在必要的参数
      if(data.data && data.data.type && data.data.event && data.data.msg) {

        //获取到传来的数据
        data = data.data;
        
        //判断数据主体类型
        switch(data.type) {
          
          //系统消息
          case 'sys':
            //交由系统消息处理函数处理
            that.systemMsgHandler(data.event, data.msg);
          break;

          //用户消息
          case 'user': 
            //交由用户消息处理函数处理
            that.userMsgHandler(data.event, data.msg);
          break;

          //其它类型消息
          default: 
            //交由其它消息处理函数处理
            that.otherMsgHandler(data.event, data.msg);
          break;
        }
      }
    }
    else if(!util.status('logined')) {

      //隐藏顶部加载图标
      wx.hideNavigationBarLoading();

      //设置服务器连接状态图标为warn
      this.setStatus('serverConnect', 'warn');

      //发生错误，显示错误
      util.showError('登录失败', '你可能不是此店铺的授权客服', data.errCode);
    
    }
    else {
      console.log('收到了不正确的信息', data);
    }
  },

  /**
   * websocket关闭处理函数
   */

  wsClose: function() {

    //判断是否登出
    if (util.status('logout')) {
        //清除状态
        util.clearStatus();
        return;
    }

    if (util.status('logout') == false) {
        wx.closeSocket();
    }

    //判断现在是否正在重连
    if(util.status('recryConnecting')) {

      //跳出防止重复重连操作
      return;
    
    }

    console.log('意外断开了WebSocket连接');

    that.target('sysMsg', 'wsErrClose');
    
    //显示顶部加载图标
    wx.showNavigationBarLoading();

    //设置开始重连
    util.status('recryConnecting', true);

    //设置当前未连接
    util.status('connected', false);

    //调用重连函数
    that.wsRecryConnect(function(unreadMsgs) {

      console.log('重连成功');

      //重连成功设置已连接
      util.status('connected', true);

      //隐藏顶部加载图标
      wx.hideNavigationBarLoading();

      that.target('sysMsg', 'wsRecryConnected', unreadMsgs);

    });

  },

  /**
   * websocket错误处理函数
   */

  wsError: function(err) {

    //判断是否登出
    if (util.status('logout')) {
        //清除状态
        util.clearStatus();
        return;
    }

    if (util.status('logout') == false) {
        wx.closeSocket();
    }

    console.log('WebSocket连接出现了错误', err);

    //判断现在是否正在重连
    if(util.status('recryConnecting')) {

      //跳出防止重复重连操作
      return;
    
    }

    that.target('sysMsg', 'wsErrClose');
    
    //显示顶部加载图标
    wx.showNavigationBarLoading();

    //设置开始重连
    util.status('recryConnecting', true);

    //设置当前未连接
    util.status('connected', false);

    //调用重连函数
    that.wsRecryConnect(function(unreadMsgs) {

      console.log('重连成功');

      //重连成功设置已连接
      util.status('connected', true);

      //隐藏顶部加载图标
      wx.hideNavigationBarLoading();

      that.target('sysMsg', 'wsRecryConnected', unreadMsgs);

    });

  },

  /**
   * 尝试重连函数
   */

  wsRecryConnect: function(callback) {

    console.log('重连机制开始重试连接');

    wx.closeSocket();

    //重连定时器
    let recryConnectInterval = setInterval(function() {

      if(util.status('authFailed')) {
        clearInterval(recryConnectInterval);
        util.status('authFailed', false);
      }

      if(util.status('recryConnectDone')) {

        util.status('recryConnectDone', false);

        //调用websocket登录函数
        that.wsLogin(util.globalData('storeId'), {

          //登录成功
          success: function() {

            util.status('recryConnectDone', true);
            
            //判断当前是否处于连接状态
            if(util.status('connected')) {

              //设定当前未进行重连
              util.status('recryConnecting', false);

              //停止重连定时器
              clearInterval(recryConnectInterval);

              //请求获取未读消息列表
              ws.request({
                storeId: util.globalData('storeId'),
                _3rdSession: util.globalData('_3rdSession'),
                _interface: 'msg/getUnreadMsgs',
                data: {}
              }, {
                success: function(data) {
                  //重连成功回调
                  callback(data.msg);
                },
                fail: function(err) {
                  that.wsClose();
                }
              });
            }
          },

          //登录失败忽略
          fail: function() {

            util.status('recryConnectDone', true);

          }
        
        });
      }
    }, 3000);
  },

  /**
   * WebSocket登录函数
   */

  wsLogin: function(storeId, callback) {

    wx.showNavigationBarLoading();

    //调用websocket连接操作函数并设置消息处理函数、连接关闭函数、连接错误函数
    ws.connect(that.wsMsgHandler, that.wsClose, that.wsError, {
      
      //websocket连接成功
      success: function() {

        console.log('连接成功，发送配对信息');

        //发送配对信息
        ws.send({

          //商户ID
          storeId: util.globalData('storeId'),
          
          //3rdSession个人凭证
          _3rdSession: wx.getStorageSync('_3rdSession')
        
        }, {

          //发送成功
          success: function() {

            console.log('发送配对信息完成');
            
            let checkConnectedInterval = setInterval(function() {
              if(util.status('connected')) {

                wx.hideNavigationBarLoading();

                clearInterval(checkConnectedInterval);

                callback.success();

                return;

              }
            }, 100);

            setTimeout(function() {
              if(!util.status('connected')) {

                wx.hideNavigationBarLoading();

                clearInterval(checkConnectedInterval);

                callback.fail(-3);

                return;

              }
            }, 10000);
          
          },

          //发送失败
          fail: function() {

            wx.hideNavigationBarLoading();

            //返回登录失败
            callback.fail(-2);
          
          }
        });
      },

      //websocket连接失败
      fail: function(err) {

        if(err && err.errCode && err.errCode != '0') {

          console.log(err);

          util.status('authFailed', true);

          let errList = {
            '-0028': '您的登录状态已失效，请重新进入小程序登录',
            '-0031': '此商户未授予您操作权限，请联系商户负责人'
          };

          wx.showModal({
            title: '授权失败',
            content: '[' + err.errCode + ']' + errList[err.errCode] + ':' + err.errMsg
          });

          callback.fail();
        }
        else {
          callback.fail(-1);
        } 
      }
    });
  }
});